# 导入LangChain的嵌入模型类
from langchain.embeddings import HuggingFaceEmbeddings

# 创建HuggingFaceEmbeddings封装器实例
# 这是一个更高级的接口，封装了底层的模型加载和推理细节
embeddings = HuggingFaceEmbeddings(
    # 指定模型路径或名称 - 有三种使用方式：

    # 方式1：使用在线模型名称（需要网络连接）
    # model_name="sentence-transformers/all-MiniLM-L6-v2", 
    # 如果不是本地路径，会从HuggingFace远程仓库下载
    # 注意：hugging face需要科学上网

    # 方式2：使用本地已下载的英文模型路径
    model_name="D:/models/sentence-transformersall-MiniLM-L6-v2",
    # 直接从本地加载，避免网络问题，加载速度更快

    # 方式3：使用本地中文优化模型路径
    # model_name="D:/models/BAAI_bge-small-zh-v1.5",
    # BAAI_bge系列是针对中文优化的嵌入模型，在中文任务上表现更好

    # 模型配置参数
    model_kwargs={'device': 'cpu'}  # 指定运行设备
    # 'cpu': 使用CPU进行计算，兼容性好
    # 'cuda': 使用GPU加速，需要安装PyTorch GPU版本
    # 'cuda:0': 指定使用第0块GPU
)

# 使用LangChain的标准接口进行文本嵌入
texts = ["这是一个测试", "这是另一个测试"]  # 输入文本列表

# 嵌入多个文档（批量处理）
vectors = embeddings.embed_documents(texts)
# embed_documents()方法特点：
# - 专门用于处理多个文档的批量嵌入
# - 自动进行批处理优化
# - 返回所有文本的嵌入向量列表

# 打印嵌入对象信息和向量类型
print(embeddings)  # 显示HuggingFaceEmbeddings对象信息
print(type(vectors))  # 输出: <class 'list'> - 返回Python原生列表
print(type(vectors[0]))  # 输出: <class 'list'> - 每个向量也是Python列表

# 如果要嵌入单个查询（如用于检索），可以使用：
# query_vector = embeddings.embed_query("单个查询文本")
# embed_query()专为查询文本优化，可能采用不同的处理策略

'''
三种嵌入方式对比：

SentenceTransformer = 本地加载模型 + 生成向量
- 最底层接口，直接控制模型
- 返回numpy数组格式
- 需要手动处理所有细节

HuggingFaceEmbeddings = 封装了 SentenceTransformer 或 HF Transformer
- 中层接口，LangChain标准化
- 返回Python列表格式
- 自动处理批处理和设备管理
- 与LangChain生态无缝集成

OllamaEmbeddings = 调用本地 Ollama 服务，模型必须先启动
- 最高层接口，通过API调用
- 依赖Ollama服务运行
- 适合模型服务化部署场景

特点总结：
HuggingFaceEmbeddings的优势：
    - 返回Python列表格式，易于处理
    - 接口标准化，与LangChain其他组件无缝集成
    - 配置参数针对LangChain优化
    - 自动处理模型加载和推理细节
    - 支持批量处理和设备管理

使用场景建议：
- 快速原型开发：使用HuggingFaceEmbeddings
- 生产环境部署：考虑OllamaEmbeddings服务化
- 底层调优：直接使用SentenceTransformer
'''

# 补充：查看嵌入向量的详细信息
print(f"文本数量: {len(texts)}")
print(f"每个文本的嵌入维度: {len(vectors[0])}")
print(f"第一个向量的前5个维度值: {vectors[0][:5]}")

# 实际应用示例：
# 1. 文档检索 - 将文档库转换为向量，查询时计算相似度
# 2. 语义搜索 - 基于语义相似度而非关键词匹配
# 3. 聚类分析 - 对文本进行自动分类
# 4. RAG系统 - 作为检索器的基础组件